package cn.itcast.filters.examples;

import java.awt.image.FilteredImageSource;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

public class ImageConvertFilter implements Filter {

    private static final boolean debug = false;
    private FilterConfig filterConfig = null;
    private java.awt.Frame frame;

    // default constructor
    public ImageConvertFilter() {
    }

    /**
     * Init method for this filter
     */
    @Override
    public void init(FilterConfig filterConfig) {
        this.filterConfig = filterConfig;
        frame = new java.awt.Frame();
        if (filterConfig != null) {
            if (debug) {
                log("ImageConvertFilter: Initializing filter");
            }
        }
    }

    /**
     * doFilter method for this filter
     */
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        if (debug) {
            log("ImageConvertFilter:doFilter()");
        }
        // get requested image full path
        String imagePath = ((HttpServletRequest) request).getServletContext().getRealPath("java-logo1.gif");
        log("Image_Path: " + imagePath);
        frame.addNotify();
        //create a dynamic image with specified image resource
        java.awt.Image image = java.awt.Toolkit.getDefaultToolkit().createImage(imagePath);
        //Track the media object status
        java.awt.MediaTracker mt = new java.awt.MediaTracker(frame);
        // add image into list which track by MediaTracker
        mt.addImage(image, 0);
        try {
            mt.waitForAll();  //wait until all image not add into list
        } catch (InterruptedException ex) {
            Logger.getLogger(ImageConvertFilter.class.getName()).log(Level.SEVERE,
                    "An InterruptedException generate while loading image", ex);
        }

        if (request instanceof HttpServletRequest) {
            // get drop-down field value from index.jsp page
            String filterType = request.getParameter("colorFilter");
            log("Filter_Type" + filterType);
            if (filterType != null) {
                if (filterType.equals("Colorless")) {
                    /*create an ImageFilter which modifies the image
                        pixels in according with RGB ColorModel.*/
                    java.awt.image.ImageFilter colorFilter =
                            new java.awt.image.RGBImageFilter() {
                                @Override
                                public int filterRGB(int x, int y, int rgb) {
                                    // Get (Red Green Blue) color intensity value
                                    int Red = (rgb & 0x00ff0000) >> 16;
                                    int Green = (rgb & 0x0000ff00) >> 8;
                                    int Blue = rgb & 0x000000ff;

                                    int Luma = (int) (0.299 * Red + 0.587 * Green + 0.114 * Blue);
                                    //Return image pixels value to ImageFilter
                                    return ((0xff << 24) | (Luma << 16) | (Luma << 8) | Luma);
                                }
                            };
                    //Creates an offScreenImage from ImageProducer and applying ImageFilter on it
                    java.awt.Image offScreenImage = frame.createImage(new FilteredImageSource(image.getSource(), colorFilter));
                    ServletOutputStream out = response.getOutputStream();
                    // Encode offScreenImage into GIF format and send to client browser
                    response.setContentType("image/gif");
                    Acme.JPM.Encoders.GifEncoder encoder =
                            new Acme.JPM.Encoders.GifEncoder(offScreenImage, out);
                    encoder.encode();
                } else if (filterType.equals("Black&White")) {
                    java.awt.image.ImageFilter colorFilter =
                            new java.awt.image.RGBImageFilter() {

                                @Override
                                public int filterRGB(int x, int y, int rgb) {
                                    int Red = (rgb & 0x00ff0000) >> 16;
                                    int Green = (rgb & 0x0000ff00) >> 8;
                                    int Blue = rgb & 0x000000ff;

                                    int V = (int) (0.615 * Red - 0.515 * Green - 0.100 * Blue);
                                    return ((0xff << 24) | (V << 16) | (V << 8) | V);
                                }
                            };
                    java.awt.Image offScreenImage =
                            frame.createImage(new FilteredImageSource(image.getSource(),
                                    colorFilter));
                    ServletOutputStream out = response.getOutputStream();
                    response.setContentType("image/gif");
                    Acme.JPM.Encoders.GifEncoder encoder =
                            new Acme.JPM.Encoders.GifEncoder(offScreenImage, out);
                    encoder.encode();
                } else {
                    java.awt.image.ImageFilter colorFilter =
                            new java.awt.image.RGBImageFilter() {

                                @Override
                                public int filterRGB(int x, int y, int rgb) {
                                    return ((rgb & 0xff00ff00) |
                                            ((rgb & 0xff0000) >> 16) | ((rgb & 0xff) << 16));
                                }
                            };
                    java.awt.Image offScreenImage =
                            frame.createImage(new FilteredImageSource(image.getSource(),
                                    colorFilter));
                    ServletOutputStream out = response.getOutputStream();
                    response.setContentType("image/gif");
                    Acme.JPM.Encoders.GifEncoder encoder =
                            new Acme.JPM.Encoders.GifEncoder(offScreenImage, out);
                    encoder.encode();
                }
            } else {
                chain.doFilter(request, response);
            }
        }
    }

    /**
     * Destroy method for this filter
     */
    @Override
    public void destroy() {
        filterConfig = null;
        frame.removeNotify();
    }

    /**
     * log method for print msg over server console
     */
    public void log(String msg) {
        filterConfig.getServletContext().log(msg);
    }
}